(Rust) Cofactor checkings
Related: (Monero) The Bug in CryptoNote protocol (2017)
libra ref
EdDSA remove small group R check
Cofactor signature checking
https://github.com/zcash-hackworks/sapling-crypto/pull/80/files
mul_by_cofactor
rand時、署名時など
生成する点がprime orderである保証はない
不要にcofactorをかけると8bit security犠牲にする
code:1.rs
/// This guarantees the point is in the prime order subgroup
#must_use
pub fn mul_by_cofactor(&self, params: &E::Params) -> Point<E, PrimeOrder>
{
let tmp = self.double(params)
.double(params)
.double(params);
convert_subgroup(&tmp)
}
as_prime_order
read時(別途、zero pointバリデーションは必要)
読み取るbytesはある点をバイトキャストしていることが前提なので。
non-prime orderの場合はError
8bit mulしないのでsecurity bitは犠牲にしない
code:1.rs
/// Attempts to cast this as a prime order element, failing if it's
/// not in the prime order subgroup.
pub fn as_prime_order(&self, params: &E::Params) -> Option<Point<E, PrimeOrder>> {
if self.mul(E::Fs::char(), params) == Point::zero() {
Some(convert_subgroup(self))
} else {
None
}
}
任意のバイト列からreadしたpointはunknownなので、as_prime_orderでprime化。
https://github.com/zcash/librustzcash/blob/9e758dc7d9fc819b67eade932a020c527d8f27b2/zcash_primitives/src/keys.rs#L134-L150
code:1.rs
pub fn read<R: Read>(mut reader: R, params: &E::Params) -> io::Result<Self> {
let ak = edwards::Point::<E, Unknown>::read(&mut reader, params)?;
let ak = match ak.as_prime_order(params) {
Some(p) => p,
None => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"ak not in prime-order subgroup",
));
}
};
if ak == edwards::Point::zero() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"ak not of prime order",
));
}
}
pointのrand生成はprime orderの保障がない
https://github.com/zcash/librustzcash/blob/05f098e893bf52946575c816b93052ca21b7ce02/librustzcash/src/tests/key_agreement.rs#L18-L22
code:1.rs
// Create random viewing key
let vk = ViewingKey::<Bls12> {
ak: edwards::Point::rand(&mut rng, &params).mul_by_cofactor(&params),
nk: edwards::Point::rand(&mut rng, &params).mul_by_cofactor(&params),
};
redjubjub public key はデフォルトでprime orderではない。
https://github.com/zcash/librustzcash/blob/05f098e893bf52946575c816b93052ca21b7ce02/sapling-crypto/src/redjubjub.rs#L41
code:1.rs
pub struct PublicKey<E: JubjubEngine>(pub Point<E, Unknown>);
https://github.com/zcash/librustzcash/blob/05f098e893bf52946575c816b93052ca21b7ce02/sapling-crypto/src/redjubjub.rs#L150-L154
code:1.rs
// 0 = h_G(-S . P_G + R + c . vk)
self.0.mul(c, params).add(&r, params).add(
&params.generator(p_g).mul(s, params).negate().into(),
params
).mul_by_cofactor(params).eq(&Point::zero())
https://github.com/zcash/librustzcash/blob/05f098e893bf52946575c816b93052ca21b7ce02/sapling-crypto/src/redjubjub.rs#L249-L270
code:1.rs
#test
fn cofactor_check() {
let rng = &mut XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);
let params = &JubjubBls12::new();
let zero = edwards::Point::zero();
let p_g = FixedGenerators::SpendingKeyGenerator;
// Get a point of order 8
let p8 = loop {
let r = edwards::Point::<Bls12, _>::rand(rng, params).mul(Fs::char(), params);
let r2 = r.double(params);
let r4 = r2.double(params);
let r8 = r4.double(params);
if r2 != zero && r4 != zero && r8 == zero {
break r;
}
};
ask -> akなどはgenerator pointがすでにprime orderであることが保障されているのでscalar mul時にcofactor mulする必要はない。
https://github.com/zcash/librustzcash/blob/3b6f5e3d5ede6469f6ae85357f0b03d4c1b45cfe/sapling-crypto/src/jubjub/mod.rs#L125
code:1.rs
/// Returns a fixed generator.
fn generator(&self, base: FixedGenerators) -> &edwards::Point<E, PrimeOrder>;
Scalar field
https://gyazo.com/bda93fb634ee1f8077010b1fb8583c7e
https://twitter.com/FiloSottile/status/1022250216509136896?s=20
Calculate circuit costs of prime group operations (Ristretto or ctEdwards-subgroup)
https://github.com/zcash/zcash/issues/4024
Improve subgroup enforcements
https://github.com/zcash-hackworks/sapling-crypto/issues/89
Montgomery curves and their arithmetic
https://arxiv.org/pdf/1703.01863v1.pdf
Faster variable-base scalar multiplication in zk-SNARK circuits
https://github.com/zcash/zcash/issues/3924#issuecomment-488028365
Understand how to optimize a circuit implementation of Groth16 verification
https://github.com/zcash/zcash/issues/3425
refs
key exchange時にボブがlow-orderなbGを渡すと、shared keyのabGからボブは8 iterationsだけでアリスの秘密鍵aを取得可能。
https://crypto.stackexchange.com/questions/12425/why-are-the-lower-3-bits-of-curve25519-ed25519-secret-keys-cleared-during-creati
#Cryptography